// 第12节：查询：find的数组查询

/* 
  这节主要学习数组的查询，在学习update时就花了重墨去讲数组的操作，可见数组的操作在MongoDB中很受重视，因为稍微
  大型一点的项目，设计的数据集合都复杂一些，都会涉及数组的操作。
*/

// 完善数据
  // 以前的我们的workmate集合对数组涉及还很少，现在在数据中加入了兴趣（interest），并且给每个人加入了一些兴趣，
  // 比如有写代码，做饭，看电影…..

  /* 
    当然这些数据你可以自己随意构建，但是如果你不想自己费事费脑，这里也为你准备好了数据，你只要把以前的表删除（drop）
    掉，重新载入(load)就可以了。
  */

var workmate1 = {
  name: 'JSPang',
  age: 33,
  sex: 1,
  job: '前端',
  skill: {
    skillOne: 'HTML+CSS',
    skillTwo: 'JavaScript',
    skillThree: 'PHP'
  },
  regeditTime: new Date(),
  interest: ['看电影', '看书', '吃美食', '钓鱼', '旅游']
}
var workmate2 = {
  name: 'ShengLei',
  age: 31,
  sex: 1,
  job: 'JAVA后端',
  skill: {
    skillOne: 'HTML+CSS',
    skillTwo: 'J2EE',
    skillThree: 'PPT'
  },
  regeditTime: new Date(),
  interest: ['篮球', '看电影', '做饭']
}
var workmate3 = {
  name: 'MinJie',
  age: 18,
  sex: 0,
  job: 'UI',
  skill: {
    skillOne: 'PhotoShop',
    skillTwo: 'UI',
    skillThree: 'PPT'
  },
  regeditTime: new Date(),
  interest: ['做饭', '画画', '看电影']
}
var workmate4 = {
  name: 'XiaoWang',
  age: 25,
  sex: 1,
  job: 'UI',
  skill: {
    skillOne: 'PhotoShop',
    skillTwo: 'UI',
    skillThree: 'PPT'
  },
  regeditTime: new Date(),
  interest: ['写代码', '篮球', '画画']
}
var workmate5 = {
  name: 'LiangPeng',
  age: 28,
  sex: 1,
  job: '前端',
  skill: {
    skillOne: 'HTML+CSS',
    skillTwo: 'JavaScript',
  },
  regeditTime: new Date(),
  interest: ['玩游戏', '写代码', '做饭']
}
var workmate6 = {
  name: 'HouFei',
  age: 25,
  sex: 0,
  job: '前端',
  skill: {
    skillOne: 'HTML+CSS',
    skillTwo: 'JavaScript',
  },
  regeditTime: new Date(),
  interest: ['化妆', '读书', '做饭']
}
var workmate7 = {
  name: 'LiuYan',
  age: 35,
  sex: 0,
  job: '美工',
  skill: {
    skillOne: 'PhotoShop',
    skillTwo: 'CAD',
  },
  regeditTime: new Date(),
  interest: ['画画', '聚会', '看电影']
}
var workmate8 = {
  name: 'DingLu',
  age: 20,
  sex: 0,
  job: '美工',
  skill: {
    skillOne: 'PhotoShop',
    skillTwo: 'CAD',
  },
  regeditTime: new Date(),
  interest: ['美食', '看电影', '做饭']
}
var workmate9 = {
  name: 'JiaPeng',
  age: 29,
  sex: 1,
  job: '前端',
  skill: {
    skillOne: 'HTML+CSS',
    skillTwo: 'JavaScript',
    skillThree: 'PHP'
  },
  regeditTime: new Date(),
  interest: ['写代码', '篮球', '游泳']
}
var workmate10 = {
  name: 'LiJia',
  age: 26,
  sex: 0,
  job: '前端',
  skill: {
    skillOne: 'HTML+CSS',
    skillTwo: 'JavaScript',
    skillThree: 'PHP'
  },
  regeditTime: new Date(),
  interest: ['玩游戏', '美食', '篮球']
}
var db = connect('demo12');
var workmateArray = [workmate1, workmate2, workmate3, workmate4, workmate5, workmate6, workmate7, workmate8, workmate9, workmate10];
db.workmate.insert(workmateArray);
print('[SUCCESS]：The data was inserted successfully');

// 基本数组查询
  /* 
    比如现在我们知道了一个人的爱好是’画画’,’聚会’,’看电影’，但我们不知道是谁，这时候我们就可以使用最简单的数组查询
    （实际工作中，这种情况基本不常用，所以这种查询只作知识点储备就可以了）
  */
  // db.workmate.find({interest:['画画','聚会','看电影']},{name:true,_id:0,interest:1,age:1})
  /* 
    结果:
    { "name" : "LiuYan", "age" : 35, "interest" : [ "画画", "聚会", "看电影" ] }
  */


  // 在终端中运行后，我们得到了数据。这时候我们说，想查出看兴趣中有看电影的员工信息。按照正常逻辑，应该使用下面的代码。
  /* 
    // 错误做法. 这个是最准确的匹配,如果有多个,则查不到
    db.workmate.find({interest:['看电影']},
      {name:1,interest:1,age:1,_id:0}
    )
  */
  /* 
    运行后，并没有如我们所愿得到相应的人员数据，数据为空。那问题出现在哪里？问题就在于我们写了一个中括号([]),
    因为加上中括号就相当于完全匹配了，所以没有得到一条符合查询条件的数据。我们去掉中括号再看看结果。
  */
  /* 
    // 正确做法
    db.workmate.find({interest:'看电影'},
      {name:1,interest:1,age:1,_id:0}
    )
  */
  /* 
    结果:
    { "name" : "JSPang", "age" : 33, "interest" : [ "看电影", "看书", "吃美食", "钓鱼", "旅游" ] }
    { "name" : "ShengLei", "age" : 31, "interest" : [ "篮球", "看电影", "做饭" ] }
    { "name" : "MinJie", "age" : 18, "interest" : [ "做饭", "画画", "看电影" ] }
    { "name" : "LiuYan", "age" : 35, "interest" : [ "画画", "聚会", "看电影" ] }
    { "name" : "DingLu", "age" : 20, "interest" : [ "美食", "看电影", "做饭" ] }
  */
  // 这就是我们在数组中查询一项的方法，这也是数组查询的最简单用法。



// $all-数组多项查询 (同时满足)
    /* 
      现在我们的条件升级了，要查询出喜欢看电影和看书的人员信息，也就是对数组中的对象进行查询，这时候要用到一个新的
      查询修饰符$all。看下面的例子：
    */
  db.workmate.find({interest:{$all:['看电影','看书']}},{name:1,_id:0,interest:1,age:1})
  /* 
    结果:
    { "name" : "JSPang", "age" : 33, "interest" : [ "看电影", "看书", "吃美食", "钓鱼", "旅游" ] }
  */


// $in-数组的或者查询 (满足其中一项即可)
    /* 
      用$all修饰符，是需要满足所有条件的，$in主要满足数组中的一项就可以被查出来（有时候会跟$or弄混）。
      比如现在要查询爱好中有看电影的或者看书的员工信息。
    */
  db.workmate.find({ interest: { $in: ['看电影', '看书'] } }, { name: 1, age: 1, _id: 0, interest: 1});
  /* 
    结果:
    { "name" : "JSPang", "age" : 33, "interest" : [ "看电影", "看书", "吃美食", "钓鱼", "旅游" ] }
    { "name" : "ShengLei", "age" : 31, "interest" : [ "篮球", "看电影", "做饭" ] }
    { "name" : "MinJie", "age" : 18, "interest" : [ "做饭", "画画", "看电影" ] }
    { "name" : "LiuYan", "age" : 35, "interest" : [ "画画", "聚会", "看电影" ] }
    { "name" : "DingLu", "age" : 20, "interest" : [ "美食", "看电影", "做饭" ] }
  */


// $size-数组个数查询
    /* 
      $size修饰符可以根据数组的数量查询出结果。比如现在我们要查找兴趣的数量是5个人员信息，这时候就可以使用$size。
    */
  db.workmate.find({interest:{$size:5}},{name:1,age:1,_id:0,interest:1})
  /* 
    结果:
    { "name" : "JSPang", "age" : 33, "interest" : [ "看电影", "看书", "吃美食", "钓鱼", "旅游" ] }
  */
  //  这时候是5项爱好的人员就会显示出来了。


// $slice-显示选项
    /* 
      有时候我并不需要显示出数组中的所有值，而是只显示前两项，比如我们现在想显示每个人兴趣的前两项，而不是把每个
      人所有的兴趣都显示出来。
    */
  // db.workmate.find({},{interest:{$slice:2},name:1,age:1,_id:0,interest:1})  //错误写法,如果有interest显示选项了,就不需要再为1了,不应该写了
  db.workmate.find({}, { interest: { $slice: 2 }, name: 1, age: 1, _id: 0})
  /* 
    结果:
    { "name" : "JSPang", "age" : 33, "interest" : [ "看电影", "看书" ] }
    { "name" : "ShengLei", "age" : 31, "interest" : [ "篮球", "看电影" ] }
    { "name" : "MinJie", "age" : 18, "interest" : [ "做饭", "画画" ] }
    { "name" : "XiaoWang", "age" : 25, "interest" : [ "写代码", "篮球" ] }
    { "name" : "LiangPeng", "age" : 28, "interest" : [ "玩游戏", "写代码" ] }
    { "name" : "HouFei", "age" : 25, "interest" : [ "化妆", "读书" ] }
    { "name" : "LiuYan", "age" : 35, "interest" : [ "画画", "聚会" ] }
    { "name" : "DingLu", "age" : 20, "interest" : [ "美食", "看电影" ] }
    { "name" : "JiaPeng", "age" : 29, "interest" : [ "写代码", "篮球" ] }
    { "name" : "LiJia", "age" : 26, "interest" : [ "玩游戏", "美食" ] }
  */

  /* 
    这时候就显示出了每个人兴趣的前两项，如果我们想显示兴趣的最后一项，可以直接使用slice:-1，来进行查询。
  */
  db.workmate.find({},{interest:{$slice:-1},name:1,age:1,_id:0})
  /* 
    结果:
    { "name" : "JSPang", "age" : 33, "interest" : [ "旅游" ] }
    { "name" : "ShengLei", "age" : 31, "interest" : [ "做饭" ] }
    { "name" : "MinJie", "age" : 18, "interest" : [ "看电影" ] }
    { "name" : "XiaoWang", "age" : 25, "interest" : [ "画画" ] }
    { "name" : "LiangPeng", "age" : 28, "interest" : [ "做饭" ] }
    { "name" : "HouFei", "age" : 25, "interest" : [ "做饭" ] }
    { "name" : "LiuYan", "age" : 35, "interest" : [ "看电影" ] }
    { "name" : "DingLu", "age" : 20, "interest" : [ "做饭" ] }
    { "name" : "JiaPeng", "age" : 29, "interest" : [ "游泳" ] }
    { "name" : "LiJia", "age" : 26, "interest" : [ "篮球" ] }
  */
